package com.fary.web.validator;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import lombok.SneakyThrows;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.math.RoundingMode;

public class ValueConstraintValidator implements ConstraintValidator<CheckValue, String> {

    private String message = "";
    private boolean notBlank = false;
    private String regex = "";
    private int integer = 0;
    private int decimal = 0;
    private long min = Long.MIN_VALUE;
    private long max = Long.MAX_VALUE;
    private boolean includeMin = true;
    private boolean includeMax = true;
    private int minLength = 0;
    private int maxLength = 4000;

    @Override
    public void initialize(CheckValue constraintAnnotation) {
        message = constraintAnnotation.message();
        regex = constraintAnnotation.regex();
        integer = constraintAnnotation.integer();
        decimal = constraintAnnotation.decimal();
        notBlank = constraintAnnotation.notBlank();
        min = constraintAnnotation.min();
        max = constraintAnnotation.max();
        includeMin = constraintAnnotation.includeMin();
        includeMax = constraintAnnotation.includeMax();
        minLength = constraintAnnotation.minLength();
        maxLength = constraintAnnotation.maxLength();
    }

    /**
     * 判断是否通过校验
     */
    @SneakyThrows
    @Override
    public boolean isValid(String value, ConstraintValidatorContext constraintContext) {
        String error = "";
        if (!notBlank && StrUtil.isBlank(value)) {
            return true;
        }
        if (StrUtil.isBlank(value)) {
            error = "不能为空！";
        }
        if (StrUtil.isBlank(error) && value.getBytes("GBK").length > maxLength) {
            error = "内容最大允许" + NumberUtil.roundStr(NumberUtil.div(maxLength, 2), 0, RoundingMode.CEILING) + "个汉字或" + maxLength + "个英文字母！";
            if (minLength == maxLength) {
                error = "内容只能是" + maxLength + "位！";
            }
        }
        if (StrUtil.isBlank(error) && value.getBytes("GBK").length < minLength) {
            error = "内容不能少于" + minLength + "位！";
            if (minLength == maxLength) {
                error = "内容只能是" + minLength + "位！";
            }
        }
        if (StrUtil.isBlank(error)) {
            try {
                double doubleValue = Double.parseDouble(value);
                if (min != Long.MIN_VALUE) {
                    if ((includeMin && doubleValue < min) || (!includeMin && doubleValue <= min)) {
                        error = includeMin ? "不能小于" + min + "！" : "必须大于" + min + "！";
                    }
                }
                if (max != Long.MAX_VALUE) {
                    if ((includeMax && doubleValue > max) || (!includeMax && doubleValue >= max)) {
                        error = "不能超过" + max + "！";
                    }
                }
            } catch (Exception ignored) {

            }
        }
        if (StrUtil.isBlank(error) && integer != 0) {
            regex = "^[1-9]\\d{0," + (integer - 1) + "}(\\.\\d{0," + decimal + "})?$|^0(\\.\\d{0," + decimal + "})?$";
            if (!Validator.isMatchRegex(regex, value)) {
                error = "整数不能超过 " + integer + "位" + (decimal != 0 ? "，小数部分不能超过" + decimal + "位！" : "！");
            }
        }
        if (StrUtil.isBlank(error) && StrUtil.isNotBlank(regex) && !Validator.isMatchRegex(regex, value)) {
            error = "数据不正确！";
        }
        if (StrUtil.isNotBlank(error)) {
            constraintContext.disableDefaultConstraintViolation();
            constraintContext.buildConstraintViolationWithTemplate(message + error).addConstraintViolation();
            return false;
        }
        return true;
    }
}
